package com.hujing.mq.config;

import com.rabbitmq.client.Channel;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Slf4j
@Data
@Configuration
@ConfigurationProperties("spring.rabbitmq")
public class MqConfig {

    private String host;
    private int port;
    private String username;
    private String password;

    //创建mq的连接工厂
    @Bean
    public ConnectionFactory connectionFactory() throws IOException {
        // CachingConnectionFactory会缓存连接和通道，提高性能
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        //设置mq的地址、端口、用户名、密码
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setPublisherReturns(true);//启用消息返回机制

        // 创建连接
        Connection connection = connectionFactory.createConnection();
        Channel channel = connection.createChannel(false);
        channel.basicQos(1);//设置每次从队列获取的消息数量

        return connectionFactory;
    }

    // 创建监听容器工厂
    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer,
                                                                               ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory listenerContainerFactory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(listenerContainerFactory, connectionFactory);
        listenerContainerFactory.setMessageConverter(new Jackson2JsonMessageConverter());
        listenerContainerFactory.setConcurrentConsumers(5);
        listenerContainerFactory.setMaxConcurrentConsumers(10);
        listenerContainerFactory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return listenerContainerFactory;
    }

    // 配置消息发送模板
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbitTemplate.setConfirmCallback((correlationData, b, s) -> {
            if (b) {
                log.info("消息发送成功");
            }else{
                log.error("消息发送失败，原因：" + s);
            }
        });
        return rabbitTemplate;
    }
}
